package hotel.controller.room;

import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;

import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;

import java.io.IOException;
import java.util.List;

import org.nutz.dao.QueryResult;
import org.nutz.dao.pager.Pager;

import hotel.common.Comm;
import hotel.common.MsgBox;
import hotel.dao.HotelDao;
import hotel.modal.Room;
import hotel.modal.RoomReserve;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.TableView;

import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;

public class RoomReserveManageController {
	@FXML
	private TableView<RoomReserve> tableView;
	@FXML
	private TableColumn<RoomReserve, String> ReserveIdCol;
	@FXML
	private TableColumn<RoomReserve, String> nameCol;
	@FXML
	private TableColumn<RoomReserve, String> phoneCol;
	@FXML
	private TableColumn<RoomReserve, String> presetTimeCol;
	@FXML
	private TableColumn<RoomReserve, String> roomNoCol;
	@FXML
	private TableColumn<RoomReserve, Integer> durationCol;
	@FXML
	private TableColumn<RoomReserve, Number> depositCol;
	@FXML
	private TableColumn<RoomReserve, Boolean> validCol;
	@FXML
	private TableColumn<RoomReserve, String> commentCol;
	@FXML
	private GridPane gridPane;
	@FXML
	private TextField condField;
	@FXML
	private ChoiceBox<String> condCh;
	@FXML
	private Button btnQuery;
	@FXML
	private Button btnRefresh;
	@FXML
	private Button btnPrevPage;
	@FXML
	private Button btnNextPage;
	@FXML
	private Button btnHomePage;
	@FXML
	private TextField pageField;
	@FXML
	private Label pageCountLabel;
	
	Pager pager = null;
	boolean condSearchMode = false;
	String col = null;
	String cond = null;
	
	
	@FXML
    public void initialize() {
		setCellFactory();
		loadData();
	}
	
	private void setCellFactory() {
		
		ReserveIdCol.setCellFactory(col -> new TableCell<RoomReserve, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		nameCol.setCellFactory(col -> new TableCell<RoomReserve, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		phoneCol.setCellFactory(col -> new TableCell<RoomReserve, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		presetTimeCol.setCellFactory(col -> new TableCell<RoomReserve, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		roomNoCol.setCellFactory(col -> new TableCell<RoomReserve, String>() {
			@Override
			protected void updateItem(String item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item);
				setAlignment(Pos.CENTER);
			}
		});
		
		durationCol.setCellFactory(col -> new TableCell<RoomReserve, Integer>() {
			@Override
			protected void updateItem(Integer item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else
					setText(item.toString());
				setAlignment(Pos.CENTER);
			}
		});
		
		depositCol.setCellFactory(col -> new TableCell<RoomReserve, Number>() {
			@Override
			protected void updateItem(Number item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == null)
					setText(null);
				else
					setText(String.format("%.2f", item));
				setAlignment(Pos.CENTER);
			}
		});
		
		validCol.setCellFactory(col -> new TableCell<RoomReserve, Boolean>() {
			@Override
			protected void updateItem(Boolean item, boolean empty) {
				super.updateItem(item, empty);
				if (empty == true)
					setText(null);
				else if (item == true)
					setText("有效");
				else
					setText("无效");
				setAlignment(Pos.CENTER);
			}
		});	
		
		tableView.setRowFactory(new Callback<TableView<RoomReserve>, TableRow<RoomReserve>>() {
			@Override
			public TableRow<RoomReserve> call(TableView<RoomReserve> param) {
				final TableRow<RoomReserve> row = new TableRow<>();

				final ContextMenu rowMenu = new ContextMenu();
				final MenuItem detailItem = new MenuItem("查看详情");
				final MenuItem changeItem = new MenuItem("更改预定");
				final MenuItem cancelItem = new MenuItem("取消预定");
				rowMenu.getItems().addAll(detailItem, changeItem, cancelItem);
				
				row.itemProperty().addListener(new ChangeListener<RoomReserve>() {
					@Override
					public void changed(ObservableValue<? extends RoomReserve> observable, RoomReserve oldValue,
							RoomReserve newValue) {
						if(newValue != null) {
							if(rowMenu.getItems().contains(changeItem) && !newValue.isValid()) {
								rowMenu.getItems().removeAll(changeItem, cancelItem);
							} else if(!rowMenu.getItems().contains(changeItem) && newValue.isValid()) {
								rowMenu.getItems().addAll(changeItem, cancelItem);
							}
						} 
					}				
				});
				
				row.setOnMouseClicked(event -> { //鼠标双击
					if (event.getClickCount() == 2 && (!row.isEmpty())) {
						itemAction(row.getItem(), 1);
					}
				});
				
				detailItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						itemAction(row.getItem(), 1);
					}
				});
				
				changeItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						itemAction(row.getItem());
					}
				});
				
				cancelItem.setOnAction(new EventHandler<ActionEvent>() {
					@Override
					public void handle(ActionEvent event) {
						RoomReserve rr = row.getItem();
						rr.setValid(false);
						Room room = HotelDao.getRoom(rr.getRoomNo());
						if(room != null) room.setStatus(1);
						if(room != null && HotelDao.update(room) && HotelDao.cancel(rr)) {
							MsgBox.showInformationDialog("提醒", null, "成功取消预定！");
						}else {
							rr.setValid(true);
							MsgBox.showErrorDialog("错误", null, "更新时发生错误！");
						}
					}
				});
				
				// only display context menu for non-null items:
				row.contextMenuProperty().bind(Bindings.when(Bindings.isNotNull(row.itemProperty())).then(rowMenu)
						.otherwise((ContextMenu) null));
				return row;
			}
		});
		
		// 监听搜索框enter键按下
		condField.setOnKeyPressed(new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent ke) {
				if (ke.getCode().equals(KeyCode.ENTER)) {
					condSearch(1);
				}
			}
		});
		
		// 监听显示页数框Enter键按下
		pageField.setOnKeyPressed(new EventHandler<KeyEvent>() {
			@Override
			public void handle(KeyEvent ke) {
				if (ke.getCode().equals(KeyCode.ENTER)) {
					int page = Integer.valueOf(pageField.getText());
					if(condSearchMode) condSearch(page);
					else showList(page);
				}
			}
		});
		
		pageField.setTextFormatter(Comm.getIntFormatter(1)); // 设置只能输入数字
	}
	
	private void loadData() {
		showList(1);
	}
	
	private void showList(int pageNumber) {
		condSearchMode = false;
		ObservableList<RoomReserve> data = tableView.getItems();
		QueryResult qrs = HotelDao.getRoomReserveList(pageNumber, 500);
		List<RoomReserve> list = qrs.getList(RoomReserve.class); 	// 获取结果集
		pager = qrs.getPager(); 									// 获取分页信息
		showPagerInfo();
		data.setAll(list);
		tableView.refresh();
	}

	// Event Listener on Button[#btnQuery].onAction
	@FXML
	public void onBtnQueryAction(ActionEvent event) {
		condSearch(1);
	}
	
	
	private void condSearch(int pageNumber) {
		condSearchMode = true;
		col = condCh.getSelectionModel().getSelectedItem();
		cond = condField.getText();
		ObservableList<RoomReserve> data = tableView.getItems();
		QueryResult qrs = HotelDao.getReserveCondSearch(col, cond, pageNumber, 500);
		List<RoomReserve> list = qrs.getList(RoomReserve.class); 	// 获取结果集
		pager = qrs.getPager(); 									// 获取分页信息
		showPagerInfo();
		data.setAll(list);
		tableView.refresh();
	}
	
	private void showPagerInfo() {
		if(pager == null) return ; 
		pageCountLabel.setText("共 " + pager.getPageCount() + " 页");
		pageField.setText(String.valueOf(pager.getPageNumber()));
		btnPrevPage.setDisable(pager.getPageNumber() <= 1);
		btnNextPage.setDisable(pager.getPageCount() == pager.getPageNumber());
	}
	
	// Event Listener on Button[#btnRefresh].onAction
	@FXML
	public void onBtnRefreshAction(ActionEvent event) {
		loadData();
	}
	
	// Event Listener on Button[#btnPrevPage].onAction
	@FXML
	public void onBtnPrevPageAction(ActionEvent event) {
		int page = pager.getPageNumber() - 1;
		if(condSearchMode)
			condSearch(page);
		else 
			showList(page);
	}
	
	// Event Listener on Button[#btnNextPage].onAction
	@FXML
	public void onBtnNextPageAction(ActionEvent event) {
		int page = pager.getPageNumber() + 1;
		if(condSearchMode)
			condSearch(page);
		else 
			showList(page);
	}
	
	// Event Listener on Button[#btnHomePage].onAction
	@FXML
	public void onBtnHomePageAction(ActionEvent event) {
		if(condSearchMode) condSearch(1);
		else  showList(1);
	}
	
	private void itemAction(RoomReserve roomReserve) {
		itemAction(roomReserve, 0);
	}
	
	private void itemAction(RoomReserve roomReserve, int mode) {
		FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/hotel/view/room/RoomReserveChange.fxml"));
		try {
			Parent root = (Parent) fxmlLoader.load();
			RoomReserveChangeController controller = fxmlLoader.<RoomReserveChangeController>getController();
			controller.setInitData(roomReserve); // 向子窗口传递数据
			if(mode == 1) controller.setReadMode();
			Stage stage = new Stage();
			stage.setScene(new Scene(root));
			if(mode == 0) stage.setTitle("预定信息修改");
			else stage.setTitle("预定详情");
			stage.setResizable(false);
			stage.initModality(Modality.APPLICATION_MODAL);
			stage.showAndWait(); // 显示窗口并等待用户操作
			if (mode == 0 && roomReserve.isModified()) { // 判断是否被修改
				if (!HotelDao.update(roomReserve)) {
					MsgBox.showErrorDialog("错误", "预定信息修改失败！", "没有成功写入数据库！");
				}
				tableView.refresh(); // 刷新表格
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
